import { Request, Response, NextFunction } from 'express';
import Organization from '@database/models/Organization';
import User from '@database/models/User';
import logger from '@utils/logger';
import { Types } from 'mongoose';

/**
 * Organization Controller
 * 组织管理控制器
 */
class OrganizationController {
  /**
   * 创建组织
   */
  async create(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { name, slug, description, website, metadata } = req.body;
      const userId = req.user?._id.toString();

      if (!userId) {
        res.status(401).json({
          success: false,
          message: 'User not authenticated'
        });
        return;
      }

      // 检查 slug 是否已存在
      const existingOrg = await Organization.findOne({ slug });
      if (existingOrg) {
        res.status(400).json({
          success: false,
          message: 'Organization slug already exists'
        });
        return;
      }

      // 创建组织
      const organization = await Organization.create({
        name,
        slug,
        description,
        website,
        metadata,
        owner: userId,
        admins: [userId],
        members: [userId],
        teams: [],
        isActive: true
      });

      // 更新用户的组织关系
      await User.findByIdAndUpdate(userId, {
        $push: {
          organizations: {
            organization: organization._id,
            roles: [], // 后续分配角色
            joinedAt: new Date(),
            isActive: true
          }
        }
      });

      res.status(201).json({
        success: true,
        message: 'Organization created successfully',
        data: organization
      });
    } catch (error) {
      logger.error('Failed to create organization:', error as Error);
      next(error);
    }
  }

  /**
   * 获取组织列表
   */
  async getAll(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { page = 1, limit = 10, search, isActive } = req.query;

      const query: any = {};
      if (search) {
        query.$or = [
          { name: { $regex: search, $options: 'i' } },
          { slug: { $regex: search, $options: 'i' } }
        ];
      }
      if (isActive !== undefined) {
        query.isActive = isActive === 'true';
      }

      const skip = (Number(page) - 1) * Number(limit);

      const [organizations, total] = await Promise.all([
        Organization.find(query)
          .populate('owner', 'username email fullName')
          .populate('admins', 'username email fullName')
          .skip(skip)
          .limit(Number(limit))
          .sort({ createdAt: -1 }),
        Organization.countDocuments(query)
      ]);

      res.json({
        success: true,
        data: {
          organizations,
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total,
            pages: Math.ceil(total / Number(limit))
          }
        }
      });
    } catch (error) {
      logger.error('Failed to get organizations:', error as Error);
      next(error);
    }
  }

  /**
   * 获取单个组织详情
   */
  async getById(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      const organization = await Organization.findById(id)
        .populate('owner', 'username email fullName avatar')
        .populate('admins', 'username email fullName avatar')
        .populate('members', 'username email fullName avatar')
        .populate('teams', 'name slug description');

      if (!organization) {
        res.status(404).json({
          success: false,
          message: 'Organization not found'
        });
        return;
      }

      res.json({
        success: true,
        data: organization
      });
    } catch (error) {
      logger.error('Failed to get organization:', error as Error);
      next(error);
    }
  }

  /**
   * 更新组织信息
   */
  async update(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { name, description, website, logo, settings, metadata } = req.body;

      const organization = await Organization.findById(id);
      if (!organization) {
        res.status(404).json({
          success: false,
          message: 'Organization not found'
        });
        return;
      }

      // 更新字段
      if (name) organization.name = name;
      if (description !== undefined) organization.description = description;
      if (website !== undefined) organization.website = website;
      if (logo !== undefined) organization.logo = logo;
      if (settings) organization.settings = { ...organization.settings, ...settings };
      if (metadata) organization.metadata = { ...organization.metadata, ...metadata };

      await organization.save();

      res.json({
        success: true,
        message: 'Organization updated successfully',
        data: organization
      });
    } catch (error) {
      logger.error('Failed to update organization:', error as Error);
      next(error);
    }
  }

  /**
   * 删除组织（软删除）
   */
  async delete(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      const organization = await Organization.findById(id);
      if (!organization) {
        res.status(404).json({
          success: false,
          message: 'Organization not found'
        });
        return;
      }

      organization.isActive = false;
      await organization.save();

      res.json({
        success: true,
        message: 'Organization deleted successfully'
      });
    } catch (error) {
      logger.error('Failed to delete organization:', error as Error);
      next(error);
    }
  }

  /**
   * 添加组织成员
   */
  async addMember(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { userId, roles = [] } = req.body;

      const organization = await Organization.findById(id);
      if (!organization) {
        res.status(404).json({
          success: false,
          message: 'Organization not found'
        });
        return;
      }

      // 检查用户是否已经是成员
      if (organization.members.some(m => m.toString() === userId)) {
        res.status(400).json({
          success: false,
          message: 'User is already a member'
        });
        return;
      }

      // 添加成员
      organization.members.push(new Types.ObjectId(userId));
      await organization.save();

      // 更新用户的组织关系
      await User.findByIdAndUpdate(userId, {
        $push: {
          organizations: {
            organization: organization._id,
            roles: roles.map((r: string) => new Types.ObjectId(r)),
            joinedAt: new Date(),
            isActive: true
          }
        }
      });

      res.json({
        success: true,
        message: 'Member added successfully'
      });
    } catch (error) {
      logger.error('Failed to add member:', error as Error);
      next(error);
    }
  }

  /**
   * 移除组织成员
   */
  async removeMember(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id, userId } = req.params;

      const organization = await Organization.findById(id);
      if (!organization) {
        res.status(404).json({
          success: false,
          message: 'Organization not found'
        });
        return;
      }

      // 不能移除所有者
      if (organization.owner.toString() === userId) {
        res.status(400).json({
          success: false,
          message: 'Cannot remove organization owner'
        });
        return;
      }

      // 移除成员
      organization.members = organization.members.filter(
        m => m.toString() !== userId
      );
      organization.admins = organization.admins.filter(
        m => m.toString() !== userId
      );
      await organization.save();

      // 更新用户的组织关系
      await User.findByIdAndUpdate(userId, {
        $pull: {
          organizations: { organization: organization._id }
        }
      });

      res.json({
        success: true,
        message: 'Member removed successfully'
      });
    } catch (error) {
      logger.error('Failed to remove member:', error as Error);
      next(error);
    }
  }

  /**
   * 获取组织成员列表
   */
  async getMembers(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { page = 1, limit = 20, search, role } = req.query;

      const organization = await Organization.findById(id);
      if (!organization) {
        res.status(404).json({
          success: false,
          message: 'Organization not found'
        });
        return;
      }

      const query: any = {
        _id: { $in: organization.members }
      };

      if (search) {
        query.$or = [
          { username: { $regex: search, $options: 'i' } },
          { email: { $regex: search, $options: 'i' } },
          { fullName: { $regex: search, $options: 'i' } }
        ];
      }

      const skip = (Number(page) - 1) * Number(limit);

      const [members, total] = await Promise.all([
        User.find(query)
          .select('username email fullName avatar status createdAt')
          .skip(skip)
          .limit(Number(limit))
          .sort({ createdAt: -1 }),
        User.countDocuments(query)
      ]);

      // 标记成员的角色（owner/admin/member）
      const membersWithRole = members.map(member => {
        const memberObj = member.toObject();
        const memberId = member._id.toString();

        if (organization.owner.toString() === memberId) {
          return { ...memberObj, organizationRole: 'owner' };
        } else if (organization.admins.some(a => a.toString() === memberId)) {
          return { ...memberObj, organizationRole: 'admin' };
        } else {
          return { ...memberObj, organizationRole: 'member' };
        }
      });

      res.json({
        success: true,
        data: {
          members: membersWithRole,
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total,
            pages: Math.ceil(total / Number(limit))
          }
        }
      });
    } catch (error) {
      logger.error('Failed to get members:', error as Error);
      next(error);
    }
  }

  /**
   * 获取用户所属的组织列表
   */
  async getUserOrganizations(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const userId = req.user?._id.toString();

      if (!userId) {
        res.status(401).json({
          success: false,
          message: 'User not authenticated'
        });
        return;
      }

      const organizations = await Organization.find({
        members: userId,
        isActive: true
      })
        .populate('owner', 'username email fullName')
        .sort({ createdAt: -1 });

      res.json({
        success: true,
        data: organizations
      });
    } catch (error) {
      logger.error('Failed to get user organizations:', error as Error);
      next(error);
    }
  }
}

export default new OrganizationController();
